package mygame;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Random;

/**
 *
 * @author Paulo Júnior
 */
public class Personagem implements Serializable
{
    private String mNome;
    private int mForca;
    private int mVigor;
    private int mAgilidade;
    private int mSangue[] = new int[2];
    private int mLevel;
    private long mExperiencia;
    private int mPontos;
    private boolean mVivo;
    private ArrayList<Arma> mArmas = new ArrayList<Arma>();
    private ArrayList<Armadura> mArmaduras = new ArrayList<Armadura>();
    private ArrayList<Pocao> mPocoes = new ArrayList<Pocao>();
    
    public Personagem(String pNome)
    {
        mNome = pNome;
        mForca = 1;
        mVigor = 1;
        mAgilidade = 1;
        mSangue[0] = 10;
        mSangue[1] = 10;
        mLevel = 1;
        mExperiencia = 0;
        mPontos = 3;
        mVivo = true;
    }
    
    public Personagem(String pNome, int pLevel)
    {
        int lPontos;
        Random lRandom = new Random();
        
        mNome = pNome;
        mForca = 1;
        mVigor = 1;
        mAgilidade = 1;
        mSangue[0] = 10;
        mSangue[1] = 10;
        mLevel = pLevel;
        mExperiencia = 0;
        mPontos = (int) (3 * Math.sqrt(mLevel)) + 6;
        mVivo = true;
        
        lPontos = lRandom.nextInt(mPontos)+1;
        mPontos -= lPontos;
        while(lPontos >= 2*mForca/3)
        {
            lPontos -= 2*mForca/3;
            mForca += 1;
        }
        
        lPontos += lRandom.nextInt(mPontos)+1;
        mPontos -= lPontos;
        while(lPontos >= 2*mAgilidade/3)
        {
            lPontos -= 2*mAgilidade/3;
            mAgilidade += 1;
        }
        
        lPontos += lRandom.nextInt(mPontos)+1;
        mPontos -= lPontos;
        while(lPontos >= 2*mVigor/3)
        {
            lPontos -= 2*mVigor/3;
            mVigor += 1;
        }
        
        lPontos += mPontos;
        mPontos = 0;
        mSangue[0] += lPontos;
        mSangue[1] += lPontos;
    }

    public String getNome()
    {
        return mNome;
    }
    
    public int getAgilidade()
    {
        return mAgilidade;
    }

    public void addAgilidade(int pAgilidade)
    {
        mAgilidade += pAgilidade;
    }

    public int getForca()
    {
        return mForca;
    }

    public void addForca(int pForca)
    {
        mForca += pForca;
    }

    public int getSangue()
    {
        return mSangue[0];
    }

    public int getSangueAtual()
    {
        return mSangue[1];
    }

    public void addSangue(int pSangue)
    {
        mSangue[0] += pSangue;
        mSangue[1] += pSangue;
    }

    public void recuperarSangue(int pSangue)
    {
        mSangue[1] += pSangue;
        if(mSangue[1] > mSangue[0])
        {
            mSangue[1] = mSangue[0];
        }
    }
    
    public void perderSangue(int pSangue)
    {
        mSangue[1] -= pSangue;
        if(mSangue[1] <= 0)
        {
            mVivo = false;
        }
    }
    
    public int getVigor()
    {
        return mVigor;
    }

    public void addVigor(int pVigor)
    {
        mVigor += pVigor;
        addSangue(pVigor*10);
    }

    public long getExperiencia()
    {
        return mExperiencia;
    }

    public void addExperiencia(long pExperiencia)
    {
        mExperiencia += pExperiencia;
        while(mExperiencia > (Math.pow(mLevel, 2) * 10))
        {
            mExperiencia -= (Math.pow(mLevel, 2) * 10);
            addLevel();
        }
    }
    
    public long geraExperiencia(int pOponenteLevel)
    {
        return Long.parseLong(String.valueOf((int)(Math.pow(mLevel, 3)*40)/(5*pOponenteLevel)));
    }
    
    public int getLevel()
    {
        return mLevel;
    }
    
    public void addLevel()
    {
        mLevel++;
        mPontos += Math.sqrt(mLevel) + 3;
    }
    
    public int getPontos()
    {
        return mPontos;
    }
    
    public void addPontos(int pPontos)
    {
        mPontos += pPontos;
    }
    
    public boolean estaVivo()
    {
        return mVivo;
    }
    
    public void setVivo(boolean pVivo)
    {
        mVivo = pVivo;
    }
    
    public int getAtaque()
    {
        return (mForca * Combate.dado(5)) + mAgilidade + (mArmas.size() > 0 && mArmas.get(0).isEquipado() ? mArmas.get(0).getDano() : 0);
    }
    
    public int getDefesa()
    {
        return (mVigor * Combate.dado(3)) + mForca + (mArmaduras.size() > 0 && mArmaduras.get(0).isEquipado() ? mArmaduras.get(0).getDefesa() : 0);
    }
    
    public int getIniciativa()
    {
        return mAgilidade * Combate.dado(5);
    }
    
    public int getPrecisao()
    {
        return mAgilidade * Combate.dado(5);
    }
    
    public int getEsquiva()
    {
        return mAgilidade * Combate.dado(3);
    }

    public void addArma(Arma pArma)
    {
        mArmas.add(pArma);
    }
    
    public void removerArma(int pIndex)
    {
        mArmas.remove(pIndex);
    }
    
    public void equiparArma(int pIndex)
    {
        Arma lArma = mArmas.get(pIndex);
        lArma.setEquipado(true);
        mArmas.get(0).setEquipado(false);
        mArmas.set(pIndex, mArmas.get(0));
        mArmas.set(0, lArma);
    }
    
    public void desequiparArma()
    {
        mArmas.get(0).setEquipado(false);
    }
    
    public void addArmadura(Armadura pArmadura)
    {
        mArmaduras.add(pArmadura);
    }
    
    public void removerArmadura(int pIndex)
    {
        mArmaduras.remove(pIndex);
    }
    
    public void equiparArmadura(int pIndex)
    {
        Armadura lArmadura = mArmaduras.get(pIndex);
        lArmadura.setEquipado(true);
        addAgilidade(lArmadura.getAgilidade());
        mArmaduras.get(0).setEquipado(false);
        mArmaduras.set(pIndex, mArmaduras.get(0));
        mArmaduras.set(0, lArmadura);
    }
    
    public void desequiparArmadura()
    {
        addAgilidade(-mArmaduras.get(0).getAgilidade());
        mArmaduras.get(0).setEquipado(false);
    }
    
    public void addPocao(Pocao pPocao)
    {
        mPocoes.add(pPocao);
    }
    
    public void removerPocao(int pIndex)
    {
        mPocoes.remove(pIndex);
    }
    
    public void usarPocao(int pIndex)
    {
        recuperarSangue(mPocoes.get(pIndex).getSangue());
        removerPocao(pIndex);
    }
}